﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Caching;
using System.Text;
using System.Web;

namespace blackhouse.mojoPortalExtend {
    internal class CachedCmsDataAccess : ICmsDataAccess {

        #region Fields

        private ICmsDataAccess dataAccess;

        #endregion

        #region Constructors

        public CachedCmsDataAccess(ICmsDataAccess decoData) {
            this.dataAccess = decoData;
        }

        #endregion

        public Guid FindPage(string url, int siteId) {
            string key = GetKey("FindPage", url, siteId);
            object data = MemoryCache.Default[key];
            Guid g = Guid.Empty;
            if (data != null)
                g = (Guid)data;

            if (g == Guid.Empty) {
                g = this.dataAccess.FindPage(url, siteId);
                this.AddCache(key, g);
            }
            return g;
        }

        private List<string> GetCacheFile() {
            string filePath = HttpContext.Current.Server.MapPath(@"~/Data/cms-data-access.cache");
            if (!File.Exists(filePath))
                File.Create(filePath).Close();
            List<string> f = new List<string>(1);
            f.Add(filePath);
            return f;
        }

        private void AddCache(string key, object data) {
            CacheItem ci = new CacheItem(key, data);
            CacheItemPolicy cip = new CacheItemPolicy();
            cip.SlidingExpiration = TimeSpan.FromMinutes(20);
            cip.ChangeMonitors.Add(new HostFileChangeMonitor(this.GetCacheFile()));
            MemoryCache.Default.Add(ci, cip);
        }

        public Guid FindPageByFunctionality(string functionality, int siteId) {
            string key = GetKey("FindPageByFunctionality", functionality, siteId);
            object data = MemoryCache.Default[key];
            Guid g = Guid.Empty;
            if (data != null)
                g = (Guid)data;

            if (g == Guid.Empty) {
                g = this.dataAccess.FindPageByFunctionality(functionality, siteId);
                this.AddCache(key, g);
            }
            return g;
        }

        public void SetCmsPageByFunctionality(string functionality, int pageId) {
            this.dataAccess.SetCmsPageByFunctionality(functionality, pageId);
            CacheChangeMonitor.Touch();
        }

        public int FindUrlByFunctionality(string functionality, int siteId) {
            string key = GetKey("FindUrlByFunctionality", functionality, siteId);
            object data = MemoryCache.Default[key];
            int urlID = 0;
            if (data != null)
                urlID = (int)data;
            else {
                urlID = this.dataAccess.FindUrlByFunctionality(functionality, siteId);
                this.AddCache(key, urlID);
            }
            return urlID;
        }

        private string GetKey(string key, params object[] parameters) {
            StringBuilder sb = new StringBuilder("CmsDataAccess" + key);
            for (int xo = 0; xo < parameters.Length; xo++) {
                sb.Append("_");
                sb.Append(parameters[xo]);
            }
            return sb.ToString();
        }

    }
}
